#ifndef __LIB_GUI_SPIRIT_H
#define __LIB_GUI_SPIRIT_H

#include<uview.h>
#include<sys/list.h>
#include"gui_image.h"
#include"gui_container.h"
#include"gui_surface.h"

typedef uint32_t gui_color_t;

//aligned type
typedef enum
{
    GUI_ALIGN_LEFT = 0,
    GUI_ALIGN_RIGHT,
    GUI_ALIGN_TOP,
    GUI_ALIGN_BOTTOM,
    GUI_ALIGN_CENTER,
    GUI_ALIGN_NONE
}gui_align_t;

//mouse cursor status
typedef enum
{
    GUI_CURSOR_NORMAL = 0,
    GUI_CURSOR_HOLD,
    GUI_CURSOR_HELP,
    GUI_CURSOR_PEN,
    GUI_CURSOR_BUSY,
    GUI_CURSOR_ACCURATE,
    GUI_CURSOR_TEXT,
    GUI_CURSOR_UNUSABLE,
    GUI_CURSOR_VRESIZE,
    GUI_CURSOR_HRESIZE,
    GUI_CURSOR_DRESIZE1,
    GUI_CURSOR_DRESIZE2,
    GUI_CURSOR_RESIZEALL,
    GUI_CURSOR_HAND,
    GUI_CURSOR_INVISIABLE,
    GUI_CURSOR_STATUS_NUM,
}gui_cursor_status_t;

typedef struct 
{
    //border 
    gui_color_t border_color;
    //background 
    gui_color_t background_color;
    gui_align_t background_align;
    //font 
    gui_color_t font_color;
    gui_align_t font_align;
    gui_cursor_status_t cursor;
    //layout
    uint16_t padding;
    uint16_t border;
    uint16_t margin;
}gui_style_t;

typedef enum
{
    GUI_SPIRIT_TYPE_UNKNOWN=0,
    GUI_SPIRIT_TYPE_WINDOW,
    GUI_SPIRIT_TYPE_LABEL,
    GUI_SPIRIT_TYPE_BUTTON,
    GUI_SPIRIT_TYPE_BOX,
    GUI_SPIRIT_TYPE_TABLE,
    GUI_SPIRIT_TYPE_FIXED,
    GUI_SPIRIT_TYPE_PBAR,
    GUI_SPIRIT_TYPE_ENTRY,
    GUI_SPIRIT_TYPE_SWITCH,
    GUI_SPIRIT_TYPE_SCROLLBAR,
    GUI_SPIRIT_TYPE_LIST,
    GUI_SPIRIT_TYPE_SELECT,
}gui_spirit_type_t;

typedef struct gui_spirit gui_spirit_t;

typedef struct gui_spirit
{
    list_t list;
    list_t signal_list;
    gui_spirit_type_t type;
    int x;
    int y;
    int width;
    int height;
    int width_min;
    int height_min;
    int visiable; //whether visiable 
    int view; 
    gui_style_t style;

    //background
    gui_image_t *background_image;
    //front 
    char *text;
    int mulline_support; 
    int max_text_len;
    int invisable_char;

    gui_image_t *image;
    gui_surface_t *surface;
    //extension
    gui_container_t *container; //spirit itself container
    gui_container_t *attached_container; //spirit attached target container

    //callback function
    void *local;
    void (*show_middle)(gui_spirit_t*);
    void (*show_bottom)(gui_spirit_t*);
}gui_spirit_t;

#define GUI_IN_SPIRIT(spirit,_x,_y) \
    ((spirit)->x<=_x&&(spirit)->y<=_y)&&\
    (_x<=(spirit)->x+(spirit)->width&&_y<=(spirit)->y+(spirit)->height)

void gui_spirit_init(gui_spirit_t *spirit, int x, int y, int width, int height);
gui_spirit_t *gui_spirit_create(int x, int y, int width, int height);
int gui_spirit_cleanup(gui_spirit_t *spirit);
int gui_spirit_destroy(gui_spirit_t *spirit);
int gui_spirit_destroy_all(gui_spirit_t *spirit);
int gui_spirit_set_pos(gui_spirit_t *spirit, int x, int y);
int gui_spirit_set_type(gui_spirit_t *spirit, gui_spirit_type_t type);
int gui_spirit_set_view(gui_spirit_t *spirit, int view);
int gui_spirit_set_size(gui_spirit_t *spirit, int width, int height);
int gui_spirit_set_size_request(gui_spirit_t *spirit, int width, int height);
int gui_spirit_set_text(gui_spirit_t *spirit, char *text);
int gui_spirit_set_text_max_len(gui_spirit_t *spirit, int maxlen);
int gui_spirit_auto_size(gui_spirit_t *spirit);
int gui_spirit_set_background_image(gui_spirit_t *spirit, char *file);
int gui_spirit_set_image(gui_spirit_t *spirit, char *file);
int gui_spirit_set_surface(gui_spirit_t *spirit, gui_surface_t *surface);
int gui_spirit_reset_size(gui_spirit_t *spirit, int width, int height);
int gui_spirit_set_container(gui_spirit_t *spirit, gui_container_t *container);
int gui_align_calc_pos(gui_style_t *style, gui_align_t align, int box_width, int box_height, int width, int height, int *out_x, int *out_y);
int gui_spirit_calc_align_pos(gui_spirit_t *spirit, int width, int height, int *out_x, int *out_y);
int gui_spirit_to_surface(gui_spirit_t *spirit);
void gui_spirit_adjust_pos_by_type_all(gui_spirit_t *spirit);
int gui_spirit_show(gui_spirit_t *spirit);
int gui_spirit_show_children(gui_spirit_t *spirit);
int gui_spirit_show_all(gui_spirit_t *spirit);
int gui_spirit_hide(gui_spirit_t *spirit);
int gui_spirit_hide_all(gui_spirit_t *spirit);

#endif 